//
//  ServerManager.swift
//  PeerTalkPlaygroundWithSPM
//
//  Created by 曾成 on 2025/1/17.
//

import Swifter
import Foundation

enum ScriptStatus: Int {
    case SUCCESS = 0
    case BAD_REQUEST
    case UUID_KEY_NOT_EXIST = -10001
    case UUID_INVALID
    case SCRIPT_KEY_NOT_EXIST 
    case SCRIPT_INVALID
    case SCRIPT_NOT_FOUND
    case SCRIPT_RUNNING
}

class ServerManager {
    
    
    
    private let server = HttpServer()
    
    @Published var serverState: Bool = false
    
    
    init() {
        
    }
    
    func stopServer() {
        server.stop()
        serverState = isServerAlive()
        print("Server stopped")
    }
    
    func isServerAlive() -> Bool {
        return server.state == .running
    }
    
    var onScriptChanged: ((_ scriptName: String, _ uuid: String) -> ScriptStatus)?
    func startServer(port: in_port_t) {
        
        server.POST["/"] = { [weak self] request in
            
            var responseJson: [String: Any] = [:]
            guard let self = self else {
                responseJson["code"] = ScriptStatus.BAD_REQUEST.rawValue
                responseJson["msg"] = "\(ScriptStatus.BAD_REQUEST)"
                return HttpResponse.ok(.text(self?.jsonDictToString(jsonDict: responseJson) ?? "")) }
            
            var bodyData = Data(request.body)
            
            // Convert the Data to a string using UTF-8 encoding
            if let bodyString = String(data: bodyData, encoding: .utf8) {
                
                let json = toJsonDictionary(jsonString: bodyString)
                
                if let scriptName = json["script"] {
                   if let uuid = json["uuid"]  {
                        if   let result =   onScriptChanged?(scriptName as! String, uuid as! String) {
                            
                            responseJson["code"] = result.rawValue
                            responseJson["msg"] = "\(result)"
                        
                        }
                   } else {
                       
                       responseJson["code"] = ScriptStatus.UUID_KEY_NOT_EXIST.rawValue
                       responseJson["msg"] = "\(ScriptStatus.UUID_KEY_NOT_EXIST)"
                   }
                } else {
                    responseJson["code"] = ScriptStatus.SCRIPT_KEY_NOT_EXIST.rawValue
                    responseJson["msg"] = "\(ScriptStatus.SCRIPT_KEY_NOT_EXIST)"
                }
                
            }
            return HttpResponse.ok(.text(jsonDictToString(jsonDict: responseJson)))
        }
        
        do {
            try server.start(port)
            
            serverState = isServerAlive()
            try print("Server started on \(server.port())")
        } catch {
            print(error)
        }
    }
    
    
   private  func jsonDictToString(jsonDict: [String: Any]) -> String {
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: jsonDict, options: [])
            if let jsonString = String(data: jsonData, encoding: .utf8) {
                return jsonString
            }
        } catch {
            print("Error creating JSON string: \(error)")
        }
        return ""
    }

    private func toJsonDictionary(jsonString: String) -> [String: Any] {
        guard let jsonData = jsonString.data(using: .utf8) else {
            return ["auth": -1]
        }
        do {
            if var jsonDictionary = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
                jsonDictionary["auth"] = 1
                return jsonDictionary
            }
        } catch {
            print(error)
        }
        return ["auth": -1]
    }

    private func uint8ToString(array: [UInt8]) -> String {
        return array.map { String(format: "%02X", $0) }.joined(separator: ":")
    }
}
